home *** CD-ROM | disk | FTP | other *** search
/ Chip: 2001 Haziran / CHIP Haziran2001.iso / prog / share / 17 / dings_e.exe / Compiler / Include / stl_list.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-08  |  17.3 KB  |  618 lines

  1. /*
  2.  *
  3.  * Copyright (c) 1994
  4.  * Hewlett-Packard Company
  5.  *
  6.  * Permission to use, copy, modify, distribute and sell this software
  7.  * and its documentation for any purpose is hereby granted without fee,
  8.  * provided that the above copyright notice appear in all copies and
  9.  * that both that copyright notice and this permission notice appear
  10.  * in supporting documentation.  Hewlett-Packard Company makes no
  11.  * representations about the suitability of this software for any
  12.  * purpose.  It is provided "as is" without express or implied warranty.
  13.  *
  14.  *
  15.  * Copyright (c) 1996,1997
  16.  * Silicon Graphics Computer Systems, Inc.
  17.  *
  18.  * Permission to use, copy, modify, distribute and sell this software
  19.  * and its documentation for any purpose is hereby granted without fee,
  20.  * provided that the above copyright notice appear in all copies and
  21.  * that both that copyright notice and this permission notice appear
  22.  * in supporting documentation.  Silicon Graphics makes no
  23.  * representations about the suitability of this software for any
  24.  * purpose.  It is provided "as is" without express or implied warranty.
  25.  */
  26.  
  27. /* NOTE: This is an internal header file, included by other STL headers.
  28.  *   You should not attempt to use it directly.
  29.  */
  30.  
  31. #ifndef __SGI_STL_INTERNAL_LIST_H
  32. #define __SGI_STL_INTERNAL_LIST_H
  33.  
  34. __STL_BEGIN_NAMESPACE
  35.  
  36. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  37. #pragma set woff 1174
  38. #endif
  39.  
  40. template <class T>
  41. struct __list_node {
  42.   typedef void* void_pointer;
  43.   void_pointer next;
  44.   void_pointer prev;
  45.   T data;
  46. };
  47.  
  48. template<class T, class Ref, class Ptr>
  49. struct __list_iterator {
  50.   typedef __list_iterator<T, T&, T*>             iterator;
  51.   typedef __list_iterator<T, const T&, const T*> const_iterator;
  52.   typedef __list_iterator<T, Ref, Ptr>           self;
  53.  
  54.   typedef bidirectional_iterator_tag iterator_category;
  55.   typedef T value_type;
  56.   typedef Ptr pointer;
  57.   typedef Ref reference;
  58.   typedef __list_node<T>* link_type;
  59.   typedef size_t size_type;
  60.   typedef ptrdiff_t difference_type;
  61.  
  62.   link_type node;
  63.  
  64.   __list_iterator(link_type x) : node(x) {}
  65.   __list_iterator() {}
  66.   __list_iterator(const iterator& x) : node(x.node) {}
  67.  
  68.   bool operator==(const self& x) const { return node == x.node; }
  69.   bool operator!=(const self& x) const { return node != x.node; }
  70.   reference operator*() const { return (*node).data; }
  71.  
  72. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  73.   pointer operator->() const { return &(operator*()); }
  74. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  75.  
  76.   self& operator++() { 
  77.     node = (link_type)((*node).next);
  78.     return *this;
  79.   }
  80.   self operator++(int) { 
  81.     self tmp = *this;
  82.     ++*this;
  83.     return tmp;
  84.   }
  85.   self& operator--() { 
  86.     node = (link_type)((*node).prev);
  87.     return *this;
  88.   }
  89.   self operator--(int) { 
  90.     self tmp = *this;
  91.     --*this;
  92.     return tmp;
  93.   }
  94. };
  95.  
  96. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  97.  
  98. template <class T, class Ref, class Ptr>
  99. inline bidirectional_iterator_tag
  100. iterator_category(const __list_iterator<T, Ref, Ptr>&) {
  101.   return bidirectional_iterator_tag();
  102. }
  103.  
  104. template <class T, class Ref, class Ptr>
  105. inline T*
  106. value_type(const __list_iterator<T, Ref, Ptr>&) {
  107.   return 0;
  108. }
  109.  
  110. template <class T, class Ref, class Ptr>
  111. inline ptrdiff_t*
  112. distance_type(const __list_iterator<T, Ref, Ptr>&) {
  113.   return 0;
  114. }
  115.  
  116. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  117.  
  118. template <class T, class Alloc = alloc>
  119. class list {
  120. protected:
  121.   typedef void* void_pointer;
  122.   typedef __list_node<T> list_node;
  123.   typedef simple_alloc<list_node, Alloc> list_node_allocator;
  124. public:      
  125.   typedef T value_type;
  126.   typedef value_type* pointer;
  127.   typedef const value_type* const_pointer;
  128.   typedef value_type& reference;
  129.   typedef const value_type& const_reference;
  130.   typedef list_node* link_type;
  131.   typedef size_t size_type;
  132.   typedef ptrdiff_t difference_type;
  133.  
  134. public:
  135.   typedef __list_iterator<T, T&, T*>             iterator;
  136.   typedef __list_iterator<T, const T&, const T*> const_iterator;
  137.  
  138. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
  139.   typedef reverse_iterator<const_iterator> const_reverse_iterator;
  140.   typedef reverse_iterator<iterator> reverse_iterator;
  141. #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  142.   typedef reverse_bidirectional_iterator<const_iterator, value_type,
  143.   const_reference, difference_type>
  144.   const_reverse_iterator;
  145.   typedef reverse_bidirectional_iterator<iterator, value_type, reference,
  146.   difference_type>
  147.   reverse_iterator; 
  148. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  149.  
  150. protected:
  151.   link_type get_node() { return list_node_allocator::allocate(); }
  152.   void put_node(link_type p) { list_node_allocator::deallocate(p); }
  153.  
  154.   link_type create_node(const T& x) {
  155.     link_type p = get_node();
  156.     __STL_TRY {
  157.       construct(&p->data, x);
  158.     }
  159.     __STL_UNWIND(put_node(p));
  160.     return p;
  161.   }
  162.   void destroy_node(link_type p) {
  163.     destroy(&p->data);
  164.     put_node(p);
  165.   }
  166.  
  167. protected:
  168.   void empty_initialize() { 
  169.     node = get_node();
  170.     node->next = node;
  171.     node->prev = node;
  172.   }
  173.  
  174.   void fill_initialize(size_type n, const T& value) {
  175.     empty_initialize();
  176.     __STL_TRY {
  177.       insert(begin(), n, value);
  178.     }
  179.     __STL_UNWIND(clear(); put_node(node));
  180.   }
  181.  
  182. #ifdef __STL_MEMBER_TEMPLATES
  183.   template <class InputIterator>
  184.   void range_initialize(InputIterator first, InputIterator last) {
  185.     empty_initialize();
  186.     __STL_TRY {
  187.       insert(begin(), first, last);
  188.     }
  189.     __STL_UNWIND(clear(); put_node(node));
  190.   }
  191. #else  /* __STL_MEMBER_TEMPLATES */
  192.   void range_initialize(const T* first, const T* last) {
  193.     empty_initialize();
  194.     __STL_TRY {
  195.       insert(begin(), first, last);
  196.     }
  197.     __STL_UNWIND(clear(); put_node(node));
  198.   }
  199.   void range_initialize(const_iterator first, const_iterator last) {
  200.     empty_initialize();
  201.     __STL_TRY {
  202.       insert(begin(), first, last);
  203.     }
  204.     __STL_UNWIND(clear(); put_node(node));
  205.   }
  206. #endif /* __STL_MEMBER_TEMPLATES */
  207.  
  208. protected:
  209.   link_type node;
  210.  
  211. public:
  212.   list() { empty_initialize(); }
  213.  
  214.   iterator begin() { return (link_type)((*node).next); }
  215.   const_iterator begin() const { return (link_type)((*node).next); }
  216.   iterator end() { return node; }
  217.   const_iterator end() const { return node; }
  218.   reverse_iterator rbegin() { return reverse_iterator(end()); }
  219.   const_reverse_iterator rbegin() const { 
  220.     return const_reverse_iterator(end()); 
  221.   }
  222.   reverse_iterator rend() { return reverse_iterator(begin()); }
  223.   const_reverse_iterator rend() const { 
  224.     return const_reverse_iterator(begin());
  225.   } 
  226.   bool empty() const { return node->next == node; }
  227.   size_type size() const {
  228.     size_type result = 0;
  229.     distance(begin(), end(), result);
  230.     return result;
  231.   }
  232.   size_type max_size() const { return size_type(-1); }
  233.   reference front() { return *begin(); }
  234.   const_reference front() const { return *begin(); }
  235.   reference back() { return *(--end()); }
  236.   const_reference back() const { return *(--end()); }
  237.   void swap(list<T, Alloc>& x) { __STD::swap(node, x.node); }
  238.   iterator insert(iterator position, const T& x) {
  239.     link_type tmp = create_node(x);
  240.     tmp->next = position.node;
  241.     tmp->prev = position.node->prev;
  242.     (link_type(position.node->prev))->next = tmp;
  243.     position.node->prev = tmp;
  244.     return tmp;
  245.   }
  246.   iterator insert(iterator position) { return insert(position, T()); }
  247. #ifdef __STL_MEMBER_TEMPLATES
  248.   template <class InputIterator>
  249.   void insert(iterator position, InputIterator first, InputIterator last);
  250. #else /* __STL_MEMBER_TEMPLATES */
  251.   void insert(iterator position, const T* first, const T* last);
  252.   void insert(iterator position,
  253.               const_iterator first, const_iterator last);
  254. #endif /* __STL_MEMBER_TEMPLATES */
  255.   void insert(iterator pos, size_type n, const T& x);
  256.   void insert(iterator pos, int n, const T& x) {
  257.     insert(pos, (size_type)n, x);
  258.   }
  259.   void insert(iterator pos, long n, const T& x) {
  260.     insert(pos, (size_type)n, x);
  261.   }
  262.  
  263.   void push_front(const T& x) { insert(begin(), x); }
  264.   void push_back(const T& x) { insert(end(), x); }
  265.   iterator erase(iterator position) {
  266.     link_type next_node = link_type(position.node->next);
  267.     link_type prev_node = link_type(position.node->prev);
  268.     prev_node->next = next_node;
  269.     next_node->prev = prev_node;
  270.     destroy_node(position.node);
  271.     return iterator(next_node);
  272.   }
  273.   iterator erase(iterator first, iterator last);
  274.   void resize(size_type new_size, const T& x);
  275.   void resize(size_type new_size) { resize(new_size, T()); }
  276.   void clear();
  277.  
  278.   void pop_front() { erase(begin()); }
  279.   void pop_back() { 
  280.     iterator tmp = end();
  281.     erase(--tmp);
  282.   }
  283.   list(size_type n, const T& value) { fill_initialize(n, value); }
  284.   list(int n, const T& value) { fill_initialize(n, value); }
  285.   list(long n, const T& value) { fill_initialize(n, value); }
  286.   explicit list(size_type n) { fill_initialize(n, T()); }
  287.  
  288. #ifdef __STL_MEMBER_TEMPLATES
  289.   template <class InputIterator>
  290.   list(InputIterator first, InputIterator last) {
  291.     range_initialize(first, last);
  292.   }
  293.  
  294. #else /* __STL_MEMBER_TEMPLATES */
  295.   list(const T* first, const T* last) { range_initialize(first, last); }
  296.   list(const_iterator first, const_iterator last) {
  297.     range_initialize(first, last);
  298.   }
  299. #endif /* __STL_MEMBER_TEMPLATES */
  300.   list(const list<T, Alloc>& x) {
  301.     range_initialize(x.begin(), x.end());
  302.   }
  303.   ~list() {
  304.     clear();
  305.     put_node(node);
  306.   }
  307.   list<T, Alloc>& operator=(const list<T, Alloc>& x);
  308.  
  309. protected:
  310.   void transfer(iterator position, iterator first, iterator last) {
  311.     if (position != last) {
  312.       (*(link_type((*last.node).prev))).next = position.node;
  313.       (*(link_type((*first.node).prev))).next = last.node;
  314.       (*(link_type((*position.node).prev))).next = first.node;  
  315.       link_type tmp = link_type((*position.node).prev);
  316.       (*position.node).prev = (*last.node).prev;
  317.       (*last.node).prev = (*first.node).prev; 
  318.       (*first.node).prev = tmp;
  319.     }
  320.   }
  321.  
  322. public:
  323.   void splice(iterator position, list& x) {
  324.     if (!x.empty()) 
  325.       transfer(position, x.begin(), x.end());
  326.   }
  327.   void splice(iterator position, list&, iterator i) {
  328.     iterator j = i;
  329.     ++j;
  330.     if (position == i || position == j) return;
  331.     transfer(position, i, j);
  332.   }
  333.   void splice(iterator position, list&, iterator first, iterator last) {
  334.     if (first != last) 
  335.       transfer(position, first, last);
  336.   }
  337.   void remove(const T& value);
  338.   void unique();
  339.   void merge(list& x);
  340.   void reverse();
  341.   void sort();
  342.  
  343. #ifdef __STL_MEMBER_TEMPLATES
  344.   template <class Predicate> void remove_if(Predicate);
  345.   template <class BinaryPredicate> void unique(BinaryPredicate);
  346.   template <class StrictWeakOrdering> void merge(list&, StrictWeakOrdering);
  347.   template <class StrictWeakOrdering> void sort(StrictWeakOrdering);
  348. #endif /* __STL_MEMBER_TEMPLATES */
  349.  
  350.   friend bool operator== __STL_NULL_TMPL_ARGS (const list& x, const list& y);
  351. };
  352.  
  353. template <class T, class Alloc>
  354. inline bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y) {
  355.   typedef typename list<T,Alloc>::link_type link_type;
  356.   link_type e1 = x.node;
  357.   link_type e2 = y.node;
  358.   link_type n1 = (link_type) e1->next;
  359.   link_type n2 = (link_type) e2->next;
  360.   for ( ; n1 != e1 && n2 != e2 ;
  361.           n1 = (link_type) n1->next, n2 = (link_type) n2->next)
  362.     if (n1->data != n2->data)
  363.       return false;
  364.   return n1 == e1 && n2 == e2;
  365. }
  366.  
  367. template <class T, class Alloc>
  368. inline bool operator<(const list<T, Alloc>& x, const list<T, Alloc>& y) {
  369.   return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
  370. }
  371.  
  372. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  373.  
  374. template <class T, class Alloc>
  375. inline void swap(list<T, Alloc>& x, list<T, Alloc>& y) {
  376.   x.swap(y);
  377. }
  378.  
  379. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  380.  
  381. #ifdef __STL_MEMBER_TEMPLATES
  382.  
  383. template <class T, class Alloc> template <class InputIterator>
  384. void list<T, Alloc>::insert(iterator position,
  385.                             InputIterator first, InputIterator last) {
  386.   for ( ; first != last; ++first)
  387.     insert(position, *first);
  388. }
  389.  
  390. #else /* __STL_MEMBER_TEMPLATES */
  391.  
  392. template <class T, class Alloc>
  393. void list<T, Alloc>::insert(iterator position, const T* first, const T* last) {
  394.   for ( ; first != last; ++first)
  395.     insert(position, *first);
  396. }
  397.  
  398. template <class T, class Alloc>
  399. void list<T, Alloc>::insert(iterator position,
  400.                             const_iterator first, const_iterator last) {
  401.   for ( ; first != last; ++first)
  402.     insert(position, *first);
  403. }
  404.  
  405. #endif /* __STL_MEMBER_TEMPLATES */
  406.  
  407. template <class T, class Alloc>
  408. void list<T, Alloc>::insert(iterator position, size_type n, const T& x) {
  409.   for ( ; n > 0; --n)
  410.     insert(position, x);
  411. }
  412.  
  413. template <class T, class Alloc>
  414. list<T,Alloc>::iterator list<T, Alloc>::erase(iterator first, iterator last) {
  415.   while (first != last) erase(first++);
  416.   return last;
  417. }
  418.  
  419. template <class T, class Alloc>
  420. void list<T, Alloc>::resize(size_type new_size, const T& x)
  421. {
  422.   iterator i = begin();
  423.   size_type len = 0;
  424.   for ( ; i != end() && len < new_size; ++i, ++len)
  425.     ;
  426.   if (len == new_size)
  427.     erase(i, end());
  428.   else                          // i == end()
  429.     insert(end(), new_size - len, x);
  430. }
  431.  
  432. template <class T, class Alloc> 
  433. void list<T, Alloc>::clear()
  434. {
  435.   link_type cur = (link_type) node->next;
  436.   while (cur != node) {
  437.     link_type tmp = cur;
  438.     cur = (link_type) cur->next;
  439.     destroy_node(tmp);
  440.   }
  441.   node->next = node;
  442.   node->prev = node;
  443. }
  444.  
  445. template <class T, class Alloc>
  446. list<T, Alloc>& list<T, Alloc>::operator=(const list<T, Alloc>& x) {
  447.   if (this != &x) {
  448.     iterator first1 = begin();
  449.     iterator last1 = end();
  450.     const_iterator first2 = x.begin();
  451.     const_iterator last2 = x.end();
  452.     while (first1 != last1 && first2 != last2) *first1++ = *first2++;
  453.     if (first2 == last2)
  454.       erase(first1, last1);
  455.     else
  456.       insert(last1, first2, last2);
  457.   }
  458.   return *this;
  459. }
  460.  
  461. template <class T, class Alloc>
  462. void list<T, Alloc>::remove(const T& value) {
  463.   iterator first = begin();
  464.   iterator last = end();
  465.   while (first != last) {
  466.     iterator next = first;
  467.     ++next;
  468.     if (*first == value) erase(first);
  469.     first = next;
  470.   }
  471. }
  472.  
  473. template <class T, class Alloc>
  474. void list<T, Alloc>::unique() {
  475.   iterator first = begin();
  476.   iterator last = end();
  477.   if (first == last) return;
  478.   iterator next = first;
  479.   while (++next != last) {
  480.     if (*first == *next)
  481.       erase(next);
  482.     else
  483.       first = next;
  484.     next = first;
  485.   }
  486. }
  487.  
  488. template <class T, class Alloc>
  489. void list<T, Alloc>::merge(list<T, Alloc>& x) {
  490.   iterator first1 = begin();
  491.   iterator last1 = end();
  492.   iterator first2 = x.begin();
  493.   iterator last2 = x.end();
  494.   while (first1 != last1 && first2 != last2)
  495.     if (*first2 < *first1) {
  496.       iterator next = first2;
  497.       transfer(first1, first2, ++next);
  498.       first2 = next;
  499.     }
  500.     else
  501.       ++first1;
  502.   if (first2 != last2) transfer(last1, first2, last2);
  503. }
  504.  
  505. template <class T, class Alloc>
  506. void list<T, Alloc>::reverse() {
  507.   if (node->next == node || link_type(node->next)->next == node) return;
  508.   iterator first = begin();
  509.   ++first;
  510.   while (first != end()) {
  511.     iterator old = first;
  512.     ++first;
  513.     transfer(begin(), old, first);
  514.   }
  515. }    
  516.  
  517. template <class T, class Alloc>
  518. void list<T, Alloc>::sort() {
  519.   if (node->next == node || link_type(node->next)->next == node) return;
  520.   list<T, Alloc> carry;
  521.   list<T, Alloc> counter[64];
  522.   int fill = 0;
  523.   while (!empty()) {
  524.     carry.splice(carry.begin(), *this, begin());
  525.     int i = 0;
  526.     while(i < fill && !counter[i].empty()) {
  527.       counter[i].merge(carry);
  528.       carry.swap(counter[i++]);
  529.     }
  530.     carry.swap(counter[i]);         
  531.     if (i == fill) ++fill;
  532.   } 
  533.  
  534.   for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1]);
  535.   swap(counter[fill-1]);
  536. }
  537.  
  538. #ifdef __STL_MEMBER_TEMPLATES
  539.  
  540. template <class T, class Alloc> template <class Predicate>
  541. void list<T, Alloc>::remove_if(Predicate pred) {
  542.   iterator first = begin();
  543.   iterator last = end();
  544.   while (first != last) {
  545.     iterator next = first;
  546.     ++next;
  547.     if (pred(*first)) erase(first);
  548.     first = next;
  549.   }
  550. }
  551.  
  552. template <class T, class Alloc> template <class BinaryPredicate>
  553. void list<T, Alloc>::unique(BinaryPredicate binary_pred) {
  554.   iterator first = begin();
  555.   iterator last = end();
  556.   if (first == last) return;
  557.   iterator next = first;
  558.   while (++next != last) {
  559.     if (binary_pred(*first, *next))
  560.       erase(next);
  561.     else
  562.       first = next;
  563.     next = first;
  564.   }
  565. }
  566.  
  567. template <class T, class Alloc> template <class StrictWeakOrdering>
  568. void list<T, Alloc>::merge(list<T, Alloc>& x, StrictWeakOrdering comp) {
  569.   iterator first1 = begin();
  570.   iterator last1 = end();
  571.   iterator first2 = x.begin();
  572.   iterator last2 = x.end();
  573.   while (first1 != last1 && first2 != last2)
  574.     if (comp(*first2, *first1)) {
  575.       iterator next = first2;
  576.       transfer(first1, first2, ++next);
  577.       first2 = next;
  578.     }
  579.     else
  580.       ++first1;
  581.   if (first2 != last2) transfer(last1, first2, last2);
  582. }
  583.  
  584. template <class T, class Alloc> template <class StrictWeakOrdering>
  585. void list<T, Alloc>::sort(StrictWeakOrdering comp) {
  586.   if (node->next == node || link_type(node->next)->next == node) return;
  587.   list<T, Alloc> carry;
  588.   list<T, Alloc> counter[64];
  589.   int fill = 0;
  590.   while (!empty()) {
  591.     carry.splice(carry.begin(), *this, begin());
  592.     int i = 0;
  593.     while(i < fill && !counter[i].empty()) {
  594.       counter[i].merge(carry, comp);
  595.       carry.swap(counter[i++]);
  596.     }
  597.     carry.swap(counter[i]);         
  598.     if (i == fill) ++fill;
  599.   } 
  600.  
  601.   for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1], comp);
  602.   swap(counter[fill-1]);
  603. }
  604.  
  605. #endif /* __STL_MEMBER_TEMPLATES */
  606.  
  607. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  608. #pragma reset woff 1174
  609. #endif
  610.  
  611. __STL_END_NAMESPACE 
  612.  
  613. #endif /* __SGI_STL_INTERNAL_LIST_H */
  614.  
  615. // Local Variables:
  616. // mode:C++
  617. // End:
  618.